﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace DataGridViewCellExtLib
{
    /// <summary>
    /// DataGridViewCell扩展类
    /// </summary>
    public static class DataGridViewCellExtension
    {
        /// <summary>
        /// 添加Panel控件到DataGridView
        /// </summary>
        /// <param name="cell">DataGridViewCell对象</param>
        /// <param name="dataGridView">DataGridView对象</param>
        /// <returns>返回已指定好大小，位置，添加到DataGridView控件的Panel对象</returns>
        /// <exception cref="ArgumentNullException">
        /// 如果cell为Null，抛出ArgumentNullException异常
        /// 如果dataGridView为Null，抛出ArgumentNullException异常
        /// </exception>
        public static Panel AddPanelControl(this DataGridViewCell cell, DataGridView dataGridView)
        {
            if (cell == null)
            {
                throw new ArgumentNullException(nameof(cell));
            }

            if (dataGridView == null)
            {
                throw new ArgumentNullException(nameof(dataGridView));
            }

            var panel = new Panel
            {
                //默认Panel颜色为透明
                BackColor = Color.Transparent
            };

            //添加控件到DataGridView
            dataGridView.Controls.Add(panel);

            //获取单元格的矩形范围
            Rectangle rectangle = dataGridView.GetCellDisplayRectangle(cell.ColumnIndex, cell.RowIndex, false);

            //设置Panel的大小
            panel.Size = new Size()
            {
                Width = rectangle.Width,
                Height = rectangle.Height
            };

            //显示Panel
            panel.Visible = true;
            //设置Panel位置
            panel.Location = new Point(rectangle.Left, rectangle.Top);

            //将Panel和DataGridViewCell绑定在一起
            panel.Tag = new TagPlus<DataGridViewCell>
            {
                Binding = cell
            };
            cell.Tag = new TagPlus<Panel>
            {
                Binding = panel
            };

            return panel;
        }

        /// <summary>
        /// 从DataGridView中移除Panel控件
        /// </summary>
        /// <param name="cell">DataGridViewCell对象</param>
        /// <param name="dataGridView">DataGridView对象</param>
        /// <exception cref="ArgumentNullException">
        /// 如果cell为Null，抛出ArgumentNullException异常
        /// 如果dataGridView为Null，抛出ArgumentNullException异常
        /// </exception>
        public static void RemovePanelControl(this DataGridViewCell cell, DataGridView dataGridView)
        {
            if (cell == null)
            {
                throw new ArgumentNullException(nameof(cell));
            }

            if (dataGridView == null)
            {
                throw new ArgumentNullException(nameof(dataGridView));
            }

            var panel = ((TagPlus<Panel>)cell.Tag).Binding;

            //移除Panel控件
            dataGridView.Controls.Remove(panel);
            panel.Dispose();
        }

        /// <summary>
        /// 重新在DataGridView控件中设置Panel位置
        /// </summary>
        /// <param name="cell">DataGridViewCell对象</param>
        /// <param name="dataGridView">DataGridView对象</param>
        /// <exception cref="ArgumentNullException">
        /// 如果cell为Null，抛出ArgumentNullException异常
        /// 如果dataGridView为Null，抛出ArgumentNullException异常
        /// </exception>
        public static void ResetPanelControlLocation(this DataGridViewCell cell, DataGridView dataGridView)
        {
            if (cell == null)
            {
                throw new ArgumentNullException(nameof(cell));
            }

            if (dataGridView == null)
            {
                throw new ArgumentNullException(nameof(dataGridView));
            }

            var tagPlus = (TagPlus<Panel>)cell.Tag;
            var panel = tagPlus.Binding;

            //获取单元格的矩形范围
            Rectangle rectangle = dataGridView.GetCellDisplayRectangle(cell.ColumnIndex, cell.RowIndex, false);
            //设置Panel位置
            panel.Location = new Point(rectangle.Left, rectangle.Top);
        }
    }

    /// <summary>
    /// Tag扩展类
    /// </summary>
    /// <typeparam name="T">需要绑定的数据类型</typeparam>
    public class TagPlus<T>
    {
        /// <summary>
        /// 需要绑定的元素
        /// </summary>
        public T Binding { get; set; }

        /// <summary>
        /// 将Control.Tag属性保留到当前属性上
        /// </summary>
        public object Tag { get; set; }
    }
}
